home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 20.1 KB | 737 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: SLFilPar.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWOS.hpp"
-
- #ifndef SLFILPAR_H
- #include "SLFilPar.h"
- #endif
-
- #ifndef FWSOMENV_H
- #include "FWSOMEnv.h"
- #endif
-
- #ifndef FWFILESP_H
- #include "FWFileSp.h"
- #endif
-
- #ifndef FWFILESY_H
- #include "FWFileSy.h"
- #endif
-
- #ifndef FWBNDSTR_H
- #include "FWBndStr.h"
- #endif
-
- #ifndef FWEXCLIB_H
- #include "FWExcLib.h"
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(FWMEMMGR_H)
- #include "FWMemMgr.h"
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(__DOS_H)
- #include <dos.h>
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(__DIRECT_H)
- #include <direct.h>
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(__IO_H)
- #include <io.h>
- #endif
-
- #ifdef FW_BUILD_WIN16
- extern "C" void FAR PASCAL DOS3Call(); // We don't do "int 21h" under Windows
- #endif
-
-
- #ifdef FW_BUILD_WIN16
- static short privPrimitiveGetDefaultDrive();
- static short privPrimitiveGetCurrentDir(FW_Char* namePtr);
- #endif
-
- #ifdef FW_BUILD_MAC
- #pragma segment File
- #endif
-
- //========================================================================================
- // CLASS FW_PrivFileSystemParser
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_IsPartialPath
- //
- // Return TRUE if pathName specifies a partial pathName.
- //
- // On Windows, only a fully qualified pathname will return FALSE. That is a path that
- // specifies a drive and directory starting from the root directory of the drive.
- // On Mac, a partial pathname is any string that starts with a path separator character.
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_PrivFileSystemParser_IsPartialPath(FW_HString pathNameRep)
- {
- FW_Boolean result = TRUE;
-
- FW_CString pathName(pathNameRep);
-
- #ifdef FW_BUILD_WIN
- if (pathName.GetByteLength() > 0)
- {
- FW_CString32 drivePathSeparator(&FW_kDriveDelimiter, 1);
- FW_CharacterPosition drivePosition;
-
- drivePathSeparator += FW_kPathDelimiter;
-
- if (pathName.FindSubString(drivePathSeparator, drivePosition))
- result = FALSE;
- }
- #endif
-
- #ifdef FW_BUILD_MAC
- if (pathName.GetByteLength() > 0)
- result = (pathName[0] == FW_kPathDelimiter);
- #endif
-
- return (result);
- }
-
-
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_AddDelimiter
- //
- // Adds a trailing backslash if appropriate. It will not add a delimiter if one already
- // exists, the path length is zero (indicating the default directory),or if the last
- // character is a colon (indicating a drive name).
- //----------------------------------------------------------------------------------------
-
- void FW_PrivFileSystemParser_AddDelimiter(FW_HString* pathNameRep)
- {
- FW_CharacterPosition lastCharacter;
-
- FW_CString pathName(*pathNameRep);
- lastCharacter = pathName.GetCharacterLength() - 1;
-
- if (lastCharacter >= 0)
- {
- #ifdef FW_BUILD_WIN
- if ((pathName[lastCharacter] != FW_kPathDelimiter) && (pathName[lastCharacter] != FW_kDriveDelimiter))
- pathName += FW_kPathDelimiter;
- #endif
-
- #ifdef FW_BUILD_MAC
- if (pathName[lastCharacter] != FW_kPathDelimiter)
- pathName += FW_kPathDelimiter;
- #endif
-
- }
- }
-
-
- #ifdef FW_BUILD_WIN16
- //----------------------------------------------------------------------------------------
- // privPrimitiveGetDefaultDrive
- //
- // Return the current default drive number where A=0, B=1, C=2, etc.
- //----------------------------------------------------------------------------------------
- short privPrimitiveGetDefaultDrive()
- {
- short driveNumber = -1;
-
- __asm {
- mov ah, 19h
- }
-
- DOS3Call();
-
- __asm {
- mov driveNumber, ax
- }
-
- return (driveNumber);
- }
- #endif
-
-
- #ifdef FW_BUILD_WIN16
- //----------------------------------------------------------------------------------------
- // privPrimitiveGetCurrentDir
- //
- // namePtr is a pointer to a buffer. On return, this buffer will contain the directory
- // name. This buffer should be at least 64 bytes long.
- // Returns an error code.
- //----------------------------------------------------------------------------------------
- short privPrimitiveGetCurrentDir(FW_Char* namePtr)
- {
- FW_PlatformError theError = FW_xNoError;
-
- __asm {
- push ds
- lds si, [namePtr]
- mov dl, 00h
- mov ah, 47h
- }
-
- DOS3Call();
-
- __asm {
- pop ds
- jc _error
- xor ax, ax
- }
-
- _error:
-
- __asm {
- mov theError, ax
- }
-
- return (theError);
- }
- #endif
-
-
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_PrivGetWorkingDirectory
- //----------------------------------------------------------------------------------------
-
- FW_PlatformError FW_PrivFileSystemParser_PrivGetWorkingDirectory(FW_HString* directoryNameRep)
- {
- FW_PlatformError theError = FW_xNoError;
-
- FW_CString directoryName(*directoryNameRep);
- directoryName = "";
-
- #ifdef FW_BUILD_WIN16
- FW_CString255 buffer;
- const FW_Char* namePtr = (const FW_Char*)buffer;
- short driveNumber = privPrimitiveGetDefaultDrive();
-
- directoryName = "";
- directoryName += (FW_Char)(driveNumber + 'a');
- directoryName += FW_kDriveDelimiter;
- directoryName += FW_kPathDelimiter;
-
- theError = privPrimitiveGetCurrentDir((FW_Char*)namePtr);
- if (theError == FW_xNoError)
- directoryName += namePtr;
- #endif
-
- #ifdef FW_BUILD_WIN32
- char* dirBuffer = new char[MAX_PATH];
- long dirNameLength = ::GetCurrentDirectory(MAX_PATH, dirBuffer);
-
- if(dirNameLength == 0)
- theError = ::GetLastError();
- else
- directoryName = dirBuffer;
-
- delete [] dirBuffer;
- #endif
-
-
- #ifdef FW_BUILD_MAC
- short vRefNum;
- long dirID;
-
- theError = ::HGetVol(NULL, &vRefNum, &dirID);
-
- if (theError == FW_xNoError)
- theError = FW_PrivFileSystemParser_MacGenerateFullPathName(vRefNum, dirID, directoryName);
-
- #endif
- return theError;
- }
-
-
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_HasExtension
- //
- // Return TRUE if the file name has a dot-extension. Return the dot position in the
- // dotPosition parameter.
- // This routine searches the string backwards for the first path delimiter it sees.
- // It then searches forwards searching for the first period it sees.
- // It returns TRUE if it finds the period.
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_PrivFileSystemParser_HasExtension(FW_HString fileNameRep,
- FW_CharacterPosition& dotPosition)
- {
- FW_CString fileName(fileNameRep);
- FW_Boolean result = FALSE;
- FW_CharacterPosition pathDelimiterPosition;
-
- dotPosition = 0;
-
- if (fileName.GetByteLength() > 0)
- {
- result = fileName.FindCharacter(FW_kPathDelimiter, pathDelimiterPosition, fileName.GetByteLength(), FW_kBackwards);
- if (!result)
- pathDelimiterPosition = -1;
-
- result = fileName.FindCharacter(FW_kExtensionDelimiter, dotPosition, pathDelimiterPosition + 1, FW_kForwards);
- }
-
- return (result);
- }
-
-
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_ChangeExtension
- //
- // Return a pathname with the specified extension attached. fileName can be a full or
- // partial pathname. If an extension already exists, it will be overwritten.
- //----------------------------------------------------------------------------------------
-
- void FW_PrivFileSystemParser_ChangeExtension(FW_HString pathNameRep,
- FW_HString extensionRep,
- FW_HString* returnNameRep)
- {
- FW_CString pathName(pathNameRep);
- FW_CString extension(extensionRep);
- FW_CString returnName(*returnNameRep);
-
- FW_CharacterPosition dotPosition;
-
- returnName = pathName;
-
- // If there is already an extension, trancate it and the dot.
- if (FW_PrivFileSystemParser_HasExtension(pathName, dotPosition))
- returnName.Truncate(dotPosition);
-
- returnName += FW_kExtensionDelimiter;
- returnName += extension;
- }
-
-
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_GetExtension
- //
- // Return the extension to this file in extension. If no extension exists, then FALSE
- // is returned, otherwise TRUE is returned.
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_PrivFileSystemParser_GetExtension(FW_HString pathNameRep,
- FW_HString* extensionRep)
- {
- FW_CString pathName(pathNameRep);
- FW_CString extension(*extensionRep);
-
- FW_CharacterPosition dotPosition;
- FW_Boolean result = FALSE;
-
- extension = "";
-
- // Delete everything before the extension, including the dot.
- if (FW_PrivFileSystemParser_HasExtension(pathName, dotPosition))
- {
- FW_LChar charToAdd;
-
- FW_CStringReader reader(pathName);
- reader.SetPosition(dotPosition + 1);
-
- while ((charToAdd = reader.GetCharacterAndAdvance()) != FW_kNulCharacter)
- extension += charToAdd;
-
- result = TRUE;
- }
-
- return (result);
- }
-
-
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_GetFileName
- //
- // Return the filename portion without any path information. The filename includes
- // the file extension.
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_PrivFileSystemParser_GetFileName(FW_HString pathNameRep,
- FW_HString* fileNameRep)
- {
- FW_CString pathName(pathNameRep);
- FW_CString fileName(*fileNameRep);
-
- FW_CharacterPosition delimiterPosition;
- FW_Boolean result = FALSE;
-
- fileName = "";
-
- if (pathName.GetByteLength() > 0)
- {
- result = pathName.FindCharacter(FW_kPathDelimiter, delimiterPosition, pathName.GetByteLength(), FW_kBackwards);
-
- #ifdef FW_BUILD_WIN
- // Only needed for Windows since path and drive delimiters are different.
- if (!result)
- result = pathName.FindCharacter(FW_kDriveDelimiter, delimiterPosition, pathName.GetByteLength(), FW_kBackwards);
- #endif
-
- if (result)
- {
- FW_CStringReader reader(pathName);
- reader.SetPosition(delimiterPosition + 1);
-
- FW_LChar charToAdd;
- while ((charToAdd = reader.GetCharacterAndAdvance()) != FW_kNulCharacter)
- fileName += charToAdd;
- }
- }
- else
- fileName = "";
-
- return (result);
- }
-
-
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_GetJustFileName
- //
- // Get the full file name and truncate off the dot and extension.
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_PrivFileSystemParser_GetJustFileName(FW_HString pathNameRep,
- FW_HString* fileNameRep)
- {
- FW_CString pathName(pathNameRep);
- FW_CString fileName(*fileNameRep);
-
- FW_CharacterPosition dotPosition;
-
- FW_Boolean result = FW_PrivFileSystemParser_GetFileName(pathName, fileName);
-
- if (FW_PrivFileSystemParser_HasExtension(fileName, dotPosition))
- fileName.Truncate(dotPosition);
-
- return (result);
- }
-
-
-
-
- //===========================================
- // Windows Routines
- //===========================================
-
- #ifdef FW_BUILD_WIN
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_WinGetPathName
- //
- // Returns the directory information in pathName. If the directory is anything but a root
- // directory, then there is no trailing backslash on the end of the path. This makes
- // it easier to create FW_PDirectorySpecification's.
- // Returns FALSE if there is no path information, otherwise returns TRUE to indicate some
- // path information was present. The information that gets returned may still be part
- // of a partial pathname.
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_PrivFileSystemParser_WinGetPathName(FW_HString fullPathNameRep,
- FW_HString* pathNameRep)
- {
- #if 1
- FW_CString fullPathName(fullPathNameRep);
- FW_CString pathName(*pathNameRep);
-
- char szFullPathName[_MAX_PATH];
- fullPathName.ExportCString(szFullPathName);
-
- char* lpszSlash = strrchr(szFullPathName, '\\');
- char* lpszColon = strrchr(szFullPathName, ':');
-
- if (lpszSlash != NULL)
- {
- if (lpszSlash > szFullPathName && *(lpszSlash - 1) == ':')
- ++ lpszSlash;
-
- *lpszSlash = 0;
- pathName = szFullPathName;
-
- return TRUE;
- }
-
- if (lpszColon != NULL)
- {
- lpszColon[1] = 0;
- pathName = szFullPathName;
-
- return TRUE;
- }
-
- return FALSE;
- #else
- //KVV This code calls FW_CString::GetLength() which does ASSERT(false) !
- //JEL, 12/12/95: I rewrote the code to use GetByteLength instead of GetLength, but this code
- // will definitely still fail since I removed StringTools. We need to
- // rewrite it to use the string searching member functions, but even
- // these aren't fully implemented yet.
- FW_CharacterPosition backSlashPosition = 0;
- FW_CharacterPosition colonPosition = 0;
- FW_CharacterPosition delimiterPosition;
-
- FW_Boolean backSlashResult = FALSE;
- FW_Boolean colonResult = FALSE;
- FW_Boolean functionResult = FALSE;
-
- pathName = "";
-
- if (fullPathName.GetByteLength() > 0)
- {
- // Search backwards for the first character in the delimiter set of '\' and ':'.
- FW_CStringTool *tool = FW_CStringTool::GetCurrentStringTool();
-
- backSlashResult = tool->FindCharacter(fullPathName, FW_kPathDelimiter, backSlashPosition, fullPathName.GetByteLength(), FW_kBackwards);
- colonResult = tool->FindCharacter(fullPathName, FW_kDriveDelimiter, colonPosition, fullPathName.GetByteLength(), FW_kBackwards);
-
- delimiterPosition = FW_Maximum(backSlashPosition, colonPosition);
-
- // If no delimiters were found, then there is no path information here.
- // Else return what path information there was.
-
- if (backSlashResult || colonResult)
- {
- if (delimiterPosition == 0)
- pathName += (char) (fullPathName[delimiterPosition]);
- else
- {
- pathName = fullPathName;
-
- if (fullPathName[delimiterPosition] == FW_kPathDelimiter)
- {
- // If the directory is the root directory, leave the trailing backslash.
- // Otherwise remove it.
- if (fullPathName[(FW_CharacterPosition)(delimiterPosition - 1)] == FW_kDriveDelimiter)
- pathName.Truncate(delimiterPosition + 1);
- else
- pathName.Truncate(delimiterPosition);
- }
- else
- pathName.Truncate(delimiterPosition + 1);
- }
-
- functionResult = TRUE;
- }
- }
-
- return (functionResult);
- #endif
- }
- #endif
-
-
- #ifdef FW_BUILD_WIN
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_WinGetDrivePath
- //
- // Returns the drive letter and colon character in drivePath if a drive was specified.
- // If no drive was specified, then FALSE is returned. The program can use this to
- // determine whether or not pathName specifies a partial path.
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_PrivFileSystemParser_WinGetDrivePath(FW_HString pathNameRep,
- FW_HString* drivePathRep)
- {
- FW_CString pathName(pathNameRep);
- FW_CString drivePath(*drivePathRep);
-
- FW_CharacterPosition delimiterPosition;
- FW_Boolean result = FALSE;
-
- drivePath = "";
-
- if (pathName.GetByteLength() > 0)
- {
- if (pathName.FindCharacter(FW_kDriveDelimiter, delimiterPosition, pathName.GetByteLength(), FW_kBackwards))
- {
- drivePath = pathName;
- drivePath.Truncate(delimiterPosition + 1);
- result = TRUE;
- }
- }
-
- return (result);
- }
- #endif
-
-
- #ifdef FW_BUILD_WIN
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_WinExpandPartialPath
- //
- // Expands a partial pathName into a full pathName based on the current drive and
- // directory.
- // On entry, pathName contains the partial pathname.
- // On exit, pathName contains the fully qualified pathname.
- //----------------------------------------------------------------------------------------
-
- void FW_PrivFileSystemParser_WinExpandPartialPath(FW_HString* pathNameRep)
- {
- FW_CString pathName(*pathNameRep);
-
- FW_PlatformError theError = FW_xNoError;
- FW_UNUSED(theError);
-
- #ifdef FW_BUILD_WIN16
- // [KVV] Instead of this tedious code, can use OpenFile(OF_PARSEā¦)
-
- if (IsPartialPath(pathName))
- {
- FW_CString drivePath;
- FW_CString tempPathName;
-
- if (WinGetDrivePath(pathName, drivePath))
- {
- // PathNames of form c:dir\file.ext are being phased out. Do not use.
- FW_ASSERT(FALSE);
- }
- else
- {
- // Both these cases are built on top of the current directory or drive.
- PrivGetWorkingDirectory(tempPathName);
-
- if ((pathName.GetByteLength() > 0) && (pathName[0] == FW_kPathDelimiter))
- {
- // In this case, the path is in the form '\dir1\file.txt'
- // So all we need to do is add the drive.
- WinGetDrivePath(tempPathName, drivePath);
-
- pathName.Prepend(drivePath);
- }
- else
- {
- // In this case, the path is in the form 'dir1\file.txt'
- // So we need to add the current working directory.
- if (pathName.GetByteLength() > 0)
- {
- AddDelimiter(tempPathName);
- tempPathName += pathName;
- }
-
- pathName = tempPathName;
- }
- }
- }
- #endif
-
- #ifdef FW_BUILD_WIN32
- // ??? This may or may not be a valid thing to do on Win32. It needs to be verified.
-
- char szPathName[_MAX_PATH];
- char szFullName[_MAX_PATH];
-
- char* filePortion;
-
- pathName.ExportCString(szPathName);
-
- long bufferSize = ::GetFullPathName(szPathName, MAX_PATH, szFullName, &filePortion);
-
- // Errors are getting eaten for now. But I still want to see them when
- // debugging - jjw 8/12/93
- if (bufferSize == 0)
- theError = ::GetLastError();
- else
- pathName = szFullName;
- #endif
- }
- #endif
-
-
- //===========================================
- // Macintosh Routines
- //===========================================
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_MacGenerateFullPathName
- //
- // Generate a pathname based on the vRefNum and dirID passed to the function. Return
- // TRUE if pathName contains a valid path including volume name. If this routine
- // returns FALSE, the contents of pathName are undefined.
- //----------------------------------------------------------------------------------------
-
- OSErr FW_PrivFileSystemParser_MacGenerateFullPathName(short vRefNum,
- long dirID,
- FW_HString* pathNameRep)
- {
- FW_CString pathName(*pathNameRep);
-
- CInfoPBRec paramBlock;
- Str255 dirName = "\p";
- OSErr theError = noErr;
- FW_CString tempString;
-
- // Casts required for compilation.
- paramBlock.dirInfo.ioNamePtr = (StringPtr) &dirName;
- paramBlock.dirInfo.ioVRefNum = vRefNum;
- paramBlock.dirInfo.ioDrParID = dirID;
- paramBlock.dirInfo.ioFDirIndex = -1;
-
- do
- {
- paramBlock.dirInfo.ioDrDirID = paramBlock.dirInfo.ioDrParID;
-
- theError = ::PBGetCatInfoSync(¶mBlock);
- if (theError != noErr)
- return (theError);
-
- // Casts required for compilation.
- tempString.ReplaceAll((FW_PascalChar*)&dirName);
- tempString += ":";
- tempString += pathName;
- pathName = tempString;
- } while (paramBlock.dirInfo.ioDrDirID != fsRtDirID);
-
- return (noErr);
- }
- #endif
-
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // FW_PrivFileSystemParser_MacGenerateDirectory
- //
- // Get the name of the directory specified
- //----------------------------------------------------------------------------------------
-
- OSErr FW_PrivFileSystemParser_MacGenerateDirectory(short vRefNum,
- long dirID,
- FW_ODirectorySpecification* directory)
- {
- CInfoPBRec paramBlock;
- Str255 dirName = "\p";
- OSErr theError = noErr;
- FSSpec theMacSpec;
-
- // Casts required for compilation.
- paramBlock.dirInfo.ioNamePtr = (StringPtr) & dirName;
- paramBlock.dirInfo.ioVRefNum = vRefNum;
- paramBlock.dirInfo.ioDrParID = dirID;
- paramBlock.dirInfo.ioFDirIndex = -1;
-
- paramBlock.dirInfo.ioDrDirID = paramBlock.dirInfo.ioDrParID;
-
- theError = ::PBGetCatInfoSync(¶mBlock);
- if (theError != noErr)
- return (theError);
-
- theError = ::FSMakeFSSpec(vRefNum, paramBlock.dirInfo.ioDrParID, dirName, &theMacSpec);
-
- if (theError != noErr)
- return (theError);
-
- FW_SOMEnvironment ev;
- directory->AssignFileSpec(ev, &theMacSpec);
- return (noErr);
- }
- #endif
-
-
-